package net.etfbl.jgroky.jdbc;

import java.sql.*;
import java.util.*;

public class DBConnection {
    
  public static DBConnection getConnectionPool() {
    return connectionPool;
  }
  
  public static void setConnectionPoolProperties(java.util.Properties properties) throws Exception{
      connectionPool = new DBConnection(properties);
  }
  
  private static DBConnection connectionPool;
  
  protected DBConnection(java.util.Properties properties)
    throws ClassNotFoundException, SQLException {

    freeConnections = new ArrayList<Connection>();
    usedConnections = new ArrayList<Connection>();
    databaseProducName = properties.getProperty("databaseProducName");
    driver = properties.getProperty("driver");
    jdbcURL = properties.getProperty("jdbcURL");
    username = properties.getProperty("username");
    password = properties.getProperty("password");
    preconnectCount = Integer.parseInt(properties.getProperty("preconnectCount"));
    maxIdleConnections =Integer.parseInt(properties.getProperty("preconnectCount"));
    maxConnections = Integer.parseInt(properties.getProperty("preconnectCount"));

    Class.forName(driver);
    for (int i = 0; i < preconnectCount; i++) {
      Connection conn = DriverManager.getConnection(
        jdbcURL, username, password);
      conn.setAutoCommit(true);
      freeConnections.add(conn);
    }
    connectCount = preconnectCount;
  }

  public synchronized Connection checkOut()
    throws SQLException {

    Connection conn = null;
    if (freeConnections.size() > 0) {
      conn = (Connection)freeConnections.get(0);
      freeConnections.remove(0);
      usedConnections.add(conn);
    } else {
      if (connectCount < maxConnections) {
        conn = DriverManager.getConnection(
          jdbcURL, username, password);
        usedConnections.add(conn);
        connectCount++;
      } else {
        try {
          wait();
          conn = (Connection)freeConnections.get(0);
          freeConnections.remove(0);
          usedConnections.add(conn);
        } catch (InterruptedException ex) {
          ex.printStackTrace();
        }
      }
    }
    return conn;
  }

  public synchronized void checkIn(Connection aConn) {
    if (aConn ==  null)
      return;
    if (usedConnections.remove(aConn)) {
      freeConnections.add(aConn);
      while (freeConnections.size() > maxIdleConnections) {
        int lastOne = freeConnections.size() - 1;
        Connection conn = (Connection)
          freeConnections.get(lastOne);
        try { conn.close(); } catch (SQLException ex) { }
        freeConnections.remove(lastOne);
      }
      notify();
    }
    
  }
  
    public String getDatabaseProducName() {
        return databaseProducName;
    }

  private String driver;
  private String jdbcURL;
  private String username;
  private String password;
  private String databaseProducName;
  private int preconnectCount;
  private int connectCount;
  private int maxIdleConnections;
  private int maxConnections;
  private ArrayList<Connection> usedConnections;
  private ArrayList<Connection> freeConnections;

}
